﻿using PLCDataCollector.Core.Entities;
using PLCDataCollector.Core.Models;
using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DbType = SqlSugar.DbType;

namespace PLCDataCollector.Services.Data
{
    public class DataService : IDataService
    {
        private readonly SqlSugarClient _db;

        public DataService(string connectionString)
        {
            _db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = connectionString,
                DbType = DbType.SqlServer,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute
            });

            // 配置实体映射（可选）
            ConfigureEntityMappings();
        }

        private void ConfigureEntityMappings()
        {
            // 如果需要，可以在这里配置更复杂的实体映射
            // 当前使用Attribute方式已经足够
        }

        public List<DeviceMapping> GetDeviceMappings(string machineId)
        {
            try
            {
                return _db.Queryable<DeviceMapping>()
                    .Where(d => d.MmachineId == machineId && d.IsActive)
                    .ToList();
            }
            catch (Exception ex)
            {
                // 记录日志
                throw new ApplicationException("获取设备映射失败", ex);
            }
        }

        public void SavePlcData(PlcDataHistory data)
        {
            try
            {
                _db.Insertable(data).ExecuteCommand();
            }
            catch (Exception ex)
            {
                // 记录日志
                throw new ApplicationException("保存PLC数据失败", ex);
            }
        }

        public void BatchSavePlcData(List<PlcDataHistory> dataList)
        {
            if (dataList == null || dataList.Count == 0)
                return;

            try
            {
                _db.Insertable(dataList).ExecuteCommand();
            }
            catch (Exception ex)
            {
                // 记录日志
                throw new ApplicationException("批量保存PLC数据失败", ex);
            }
        }

        public List<PlcDataHistory> GetRecentData(string machineId = null, int limit = 100)
        {
            try
            {
                var query = _db.Queryable<PlcDataHistory>();

                if (!string.IsNullOrEmpty(machineId))
                {
                    query = query.Where(d => d.MachineId == machineId);
                }

                return query.OrderBy(d => d.CollectionTime, OrderByType.Desc)
                           .Take(limit)
                           .ToList();
            }
            catch (Exception ex)
            {
                // 记录日志
                throw new ApplicationException("获取历史数据失败", ex);
            }
        }
        public List<DeviceMappingDetail> GetList(string mmachineId, string machineid, int type, int limit = 1000)
        {
            try
            {
                var query = _db.Queryable<DeviceMappingDetail>().Where(x => x.MmachineId == mmachineId && x.MachineId == machineid && (x.Type == type || x.Type == 2));

                return query.Take(limit)
                           .ToList();
            }
            catch (Exception ex)
            {
                // 记录日志
                throw new ApplicationException("获取历史数据失败", ex);
            }
        }

        public bool ChangeInfo(string MmachineId, List<GetInfoModel> infos, List<GetDetailInfoModel> detailsInfos)
        {
            try
            {
                var delete1 = _db.Deleteable<DeviceMapping>().Where(x => x.MmachineId == MmachineId).ExecuteCommand();
                var delete2 = _db.Deleteable<DeviceMappingDetail>().Where(x => x.MmachineId == MmachineId).ExecuteCommand();

                var deviceMappings = infos.Select(x => new DeviceMapping
                {
                    MmachineId = x.MmachineId.Trim(),
                    MachineId = x.MachineId.Trim(),
                    Ip = x.Ip,
                    Port = x.Port,
                    ProtocolType = x.ProtocolType,
                    IsActive = x.IsActive == 1 ? true : false,
                    Description = x.Description
                }).ToList();

                var details = detailsInfos.Select(x => new DeviceMappingDetail
                {
                    MmachineId = x.MmachineId.Trim(),
                    MachineId = x.MachineId.Trim(),
                    DataAddress = x.DataAddress.Trim(),
                    DataName = x.DataName.Trim(),
                    DataType = x.DataType.Trim(),
                    Type = x.Type,
                    IsActive = x.IsActive == 1 ? true : false,
                    MachineName = string.IsNullOrWhiteSpace(x.MachineName) ? x.MachineId : x.MachineName
                }).ToList();

                var number1 = _db.Insertable(deviceMappings).ExecuteCommand() > 0;
                var number2 = _db.Insertable(details).ExecuteCommand() > 0;
                return number2;
            }
            catch (Exception ex)
            {
                // 记录日志
                throw new ApplicationException("获取历史数据失败", ex);
            }
        }
        public List<T> ExecuteLinkedStoredProcedure<T>(string server, string database, string procedure, params SugarParameter[] parameters)
        {
            string fullProcedurePath = $"[{server}].[{database}].dbo.[{procedure}]";
            string parameterString = string.Join(", ", parameters.Select(p => p.ParameterName));

            string sql = $"EXEC {fullProcedurePath} {parameterString}";

            return _db.Ado.SqlQuery<T>(sql, parameters);
        }
        public bool TestConnection()
        {
            try
            {
                _db.Ado.ExecuteCommand("SELECT 1");
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}
